/*
 * Copyright 2012 Gregor Schauer
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package at.schauer.gregor.vienna;

import at.schauer.gregor.vienna.context.DefaultViennaContext;
import at.schauer.gregor.vienna.context.ViennaContext;
import at.schauer.gregor.vienna.metadata.JPAMetadataProvider;
import at.schauer.gregor.vienna.serializer.DefaultSerializer;
import at.schauer.gregor.vienna.serializer.decomposer.DirectFieldDecomposer;
import at.schauer.gregor.vienna.serializer.populator.DirectFieldPopulator;
import at.schauer.gregor.vienna.test.Visitor;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.Properties;

/**
 * @author Gregor Schauer
 */
@Configuration
@EnableTransactionManagement
public class HibernateTestConfig {
	@Bean
	public SessionFactory sessionFactory() throws IOException {
		LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
		sessionFactoryBean.setPackagesToScan(Visitor.class.getPackage().getName());
		sessionFactoryBean.setDataSource(dataSource());
		sessionFactoryBean.setHibernateProperties(hibernateProperties());
		sessionFactoryBean.afterPropertiesSet();
		return sessionFactoryBean.getObject();
	}

	@Bean
	public Properties hibernateProperties() {
		Properties properties = new Properties();
		properties.setProperty("hibernate.hbm2ddl.auto", "create");
		properties.setProperty("javax.persistence.validation.mode", "none");
		return properties;
	}

	@Bean
	public DataSource dataSource() {
		EmbeddedDatabaseBuilder databaseBuilder = new EmbeddedDatabaseBuilder();
		databaseBuilder.setType(EmbeddedDatabaseType.HSQL);
		return databaseBuilder.build();
	}

	@Bean
	public ViennaContext viennaContext() {
		DefaultViennaContext ctx = new DefaultViennaContext();
		ctx.getMetadataProviderMap().put(Object.class, new JPAMetadataProvider<Object>());
		ctx.getSerializerMap().put(Object.class, serializer());
		return ctx;
	}

	@Bean
	public DefaultSerializer<?> serializer() {
		DefaultSerializer<Object> serializer = new DefaultSerializer<Object>();
		serializer.getDecomposerMap().put(Object.class, new DirectFieldDecomposer<Object>());
		serializer.getPopulatorMap().put(Object.class, new DirectFieldPopulator<Object>());
		return serializer;
	}

	@Bean
	public PlatformTransactionManager transactionManager() throws IOException {
		return new HibernateTransactionManager(sessionFactory());
	}
}
